home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / Packet.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  23KB  |  1,067 lines

  1. /*
  2. **    Packet.c
  3. **
  4. **    Support routines for the `packet window'
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Maximum size of the packet line buffer. */
  17.  
  18. #define MAX_PACKET_LINE_LENGTH    1024
  19.  
  20.     /* Some private data required to handle both the window,
  21.      * the editing functions and the command history buffer.
  22.      */
  23.  
  24. STATIC STRPTR                    PacketContents;
  25. STATIC STRPTR                    PacketTempBuffer;
  26.  
  27. STATIC struct Process *            PacketProcess;
  28. STATIC struct SignalSemaphore    PacketSemaphore;
  29.  
  30. STATIC LONG                        PacketLine;
  31. STATIC LONG                        PacketCount;
  32.  
  33. STATIC BOOL                        HasList    = FALSE;
  34. STATIC BOOL                        Echo    = -1;
  35.  
  36. STATIC BYTE                        PacketSignal;
  37.  
  38.     /* Gadget IDs */
  39.  
  40. enum    {    GAD_STRING, GAD_LIST };
  41.  
  42.     /* The menu to attach to the packet window. */
  43.  
  44. enum    {    MEN_LOADHISTORY=1,MEN_SAVEHISTORY,MEN_CLEARHISTORY,
  45.             MEN_OTHERWINDOW,MEN_TOGGLE_ECHO,MEN_QUITPANEL
  46.         };
  47.  
  48. STATIC VOID
  49. PacketDestructor(struct MsgItem *UnusedItem)
  50. {
  51.     Signal((struct Task *)PacketProcess,1L << PacketSignal);
  52. }
  53.  
  54. STATIC VOID
  55. PacketOutput(APTR Data,LONG Size,LONG Type)
  56. {
  57.     struct DataMsg Msg;
  58.  
  59.     InitMsgItem(&Msg,PacketDestructor);
  60.  
  61.     Msg.Type = Type;
  62.     Msg.Data = Data;
  63.     Msg.Size = Size;
  64.  
  65.     Forbid();
  66.  
  67.     ClrSignal(1L << PacketSignal);
  68.  
  69.     PutMsgItem(SpecialQueue,(struct MsgItem *)&Msg);
  70.  
  71.     Wait(1L << PacketSignal);
  72.  
  73.     Permit();
  74. }
  75.  
  76. STATIC VOID
  77. PacketWriteString(APTR Data,LONG Size)
  78. {
  79.     LONG Type;
  80.  
  81.     if(Echo == FALSE)
  82.         Type = DATAMSGTYPE_WRITESTRING_NOECHO;
  83.     else
  84.         Type = DATAMSGTYPE_WRITESTRING;
  85.  
  86.     PacketOutput(Data,Size,Type);
  87. }
  88.  
  89. STATIC VOID
  90. PacketSerialCommand(APTR Data,LONG Size)
  91. {
  92.     LONG Type;
  93.  
  94.     if(Echo == FALSE)
  95.         Type = DATAMSGTYPE_SERIALCOMMANDNOECHO;
  96.     else
  97.         Type = DATAMSGTYPE_SERIALCOMMAND;
  98.  
  99.     PacketOutput(Data,Size,Type);
  100. }
  101.  
  102.     /* CreateAllGadgets():
  103.      *
  104.      *    Create the packet string gadget.
  105.      */
  106.  
  107. STATIC struct Gadget *
  108. CreateAllGadgets(LONG Width,LONG Height,LONG *MinHeight,struct Gadget **GadgetArray,struct Gadget **GadgetList,APTR LocalVisualInfo)
  109. {
  110.     STATIC struct Hook PacketHook;
  111.  
  112.     struct Gadget        *Gadget;
  113.     struct NewGadget     NewGadget;
  114.  
  115.     InitHook(&PacketHook,(HOOKFUNC)CommonEditRoutine,NULL);
  116.  
  117.     ObtainSemaphore(&PacketSemaphore);
  118.  
  119.     memset(&NewGadget,0,sizeof(struct NewGadget));
  120.  
  121.     if(Gadget = CreateContext(GadgetList))
  122.     {
  123.         LONG Rest,StringHeight,ProtoHeight;
  124.  
  125.         StringHeight    = 3 + TextAttr.tta_YSize + 3;
  126.         ProtoHeight        = Window->WScreen->WBorTop + Window->WScreen->Font->ta_YSize + 1 + 1 + StringHeight + 1 + Window->WScreen->WBorBottom;
  127.         Rest            = (Height - 2 - ProtoHeight - 2) / TextAttr.tta_YSize;
  128.  
  129.         if(MinHeight)
  130.             *MinHeight = ProtoHeight;
  131.  
  132.         NewGadget.ng_Width        = Width - 26;
  133.         NewGadget.ng_Height        = StringHeight;
  134.         NewGadget.ng_GadgetText    = NULL;
  135.         NewGadget.ng_TextAttr    = (struct TextAttr *)&TextAttr;
  136.         NewGadget.ng_VisualInfo    = LocalVisualInfo;
  137.         NewGadget.ng_GadgetID    = GAD_STRING;
  138.         NewGadget.ng_Flags        = 0;
  139.         NewGadget.ng_LeftEdge    = 6;
  140.         NewGadget.ng_TopEdge    = Window->WScreen->WBorTop + Window->WScreen->Font->ta_YSize + 2;
  141.  
  142.         GadgetArray[GAD_STRING] = Gadget = CreateGadget(STRING_KIND,Gadget,&NewGadget,
  143.             GTST_MaxChars,    MAX_PACKET_LINE_LENGTH - 1,
  144.             GTST_EditHook,    &PacketHook,
  145.             GA_TabCycle,    FALSE,
  146.         TAG_DONE);
  147.  
  148.             /* If the window is large enough to display the
  149.              * list, create the list view gadget.
  150.              */
  151.  
  152.         if(Rest > 0)
  153.         {
  154.             NewGadget.ng_Height        = 2 + Rest * TextAttr.tta_YSize + 2 + StringHeight;
  155.             NewGadget.ng_GadgetID    = GAD_LIST;
  156.  
  157.             GadgetArray[GAD_LIST] = Gadget = CreateGadget(LISTVIEW_KIND,Gadget,&NewGadget,
  158.                 GTLV_ShowSelected,    GadgetArray[GAD_STRING],
  159.                 GTLV_Labels,        &PacketHistoryList,
  160.                 GTLV_Selected,        PacketLine,
  161.             TAG_DONE);
  162.  
  163.             if(Gadget)
  164.                 HasList = TRUE;
  165.             else
  166.                 HasList = FALSE;
  167.         }
  168.         else
  169.             HasList = FALSE;
  170.     }
  171.  
  172.     ReleaseSemaphore(&PacketSemaphore);
  173.  
  174.     return(Gadget);
  175. }
  176.  
  177. STATIC VOID
  178. HandlePacketGadgetEvent(UWORD QualifierCode)
  179. {
  180.     BOOL Activate,NeedChange,AddIt;
  181.     UWORD Qualifier,Code;
  182.     struct Node *Node;
  183.  
  184.     Qualifier    = QualifierCode >> 8;
  185.     Code        = QualifierCode & 0xFF;
  186.     Activate    = TRUE;
  187.     NeedChange    = FALSE;
  188.  
  189.     switch(Qualifier)
  190.     {
  191.         case 0xFF:
  192.  
  193.             switch(Code)
  194.             {
  195.                 case CONTROL_('S'):
  196.                 case CONTROL_('Q'):
  197.  
  198.                     PacketTempBuffer[0] = Code;
  199.                     PacketWriteString(PacketTempBuffer,1);
  200.                     break;
  201.  
  202.                 case '\r':
  203.  
  204.                     LimitedStrcpy(MAX_PACKET_LINE_LENGTH,PacketTempBuffer,PacketContents);
  205.  
  206.                         /* Add the line unless it is already in the history list. */
  207.  
  208.                     AddIt = TRUE;
  209.  
  210.                     if(PacketLine != -1)
  211.                     {
  212.                         if(Node = GetListNode(PacketLine,&PacketHistoryList))
  213.                         {
  214.                             if(!Stricmp(Node->ln_Name,PacketTempBuffer))
  215.                                 AddIt = FALSE;
  216.                         }
  217.                     }
  218.  
  219.                     if(AddIt)
  220.                         AddPacketHistory(PacketTempBuffer);
  221.  
  222.                     PacketLine = -1;
  223.                     NeedChange = TRUE;
  224.  
  225.                     LimitedStrcat(MAX_PACKET_LINE_LENGTH,PacketTempBuffer,"\\r");
  226.                     PacketSerialCommand(PacketTempBuffer,strlen(PacketTempBuffer));
  227.                     break;
  228.  
  229.                 case '\n':
  230.  
  231.                     Activate = FALSE;
  232.                     break;
  233.             }
  234.  
  235.             break;
  236.  
  237.         default:
  238.  
  239.                 /* Clear the history list when pressing Amiga+Del/Amiga+Backspace */
  240.  
  241.             if((Qualifier & (AMIGARIGHT | AMIGALEFT)) && (Code == DEL_CODE || Code == BACKSPACE_CODE))
  242.             {
  243.                 ClearPacketHistory();
  244.  
  245.                 PacketCount = 0;
  246.                 PacketLine = -1;
  247.  
  248.                 NeedChange = TRUE;
  249.  
  250.                 break;
  251.             }
  252.  
  253.                 /* This looks like a function key. Send the corresponding macro. */
  254.  
  255.             if(Code >= F01_CODE && Code <= F10_CODE)
  256.             {
  257.                 STRPTR String;
  258.                 LONG Index;
  259.  
  260.                 Index = Code - F01_CODE;
  261.  
  262.                     /* Pick the right macro */
  263.  
  264.                 if(Qualifier & CONTROL_KEY)
  265.                     String = MacroKeys->Keys[3][Index];
  266.                 else
  267.                 {
  268.                     if(Qualifier & ALT_KEY)
  269.                         String = MacroKeys->Keys[2][Index];
  270.                     else
  271.                     {
  272.                         if(Qualifier & SHIFT_KEY)
  273.                             String = MacroKeys->Keys[1][Index];
  274.                         else
  275.                             String = MacroKeys->Keys[0][Index];
  276.                     }
  277.                 }
  278.  
  279.                     /* Anything to do? */
  280.  
  281.                 if(String[0])
  282.                 {
  283.                         /* This should really insert the macro at the current
  284.                          * cursor position, but due to some strange reasons
  285.                          * we can't get the position reliably.
  286.                          */
  287.  
  288.                     LimitedStrcpy(MAX_PACKET_LINE_LENGTH,PacketTempBuffer,PacketContents);
  289.                     LimitedStrcat(MAX_PACKET_LINE_LENGTH,PacketTempBuffer,String);
  290.  
  291.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  292.                         GTST_String,        PacketTempBuffer,
  293.                     TAG_DONE);
  294.  
  295.                         /* Now, that's really nasty... */
  296.  
  297.                     ((struct StringInfo *)PacketGadgetArray[GAD_STRING]->SpecialInfo)->BufferPos = strlen(PacketTempBuffer);
  298.                 }
  299.  
  300.                 break;
  301.             }
  302.  
  303.                 /* The user pressed the cursor-up key to
  304.                  * scroll through the command history.
  305.                  */
  306.  
  307.             if(Code == CURSORUP)
  308.             {
  309.                     /* Shift key: jump to first command
  310.                      * history entry.
  311.                      */
  312.  
  313.                 if(Qualifier & SHIFT_KEY)
  314.                 {
  315.                     if(IsListEmpty(&PacketHistoryList))
  316.                         PacketLine = -1;
  317.                     else
  318.                     {
  319.                         NeedChange = TRUE;
  320.                         PacketLine = 0;
  321.                     }
  322.                 }
  323.                 else
  324.                 {
  325.                     if(PacketLine == -1)
  326.                     {
  327.                         NeedChange = TRUE;
  328.                         PacketLine = PacketCount - 1;
  329.                     }
  330.                     else
  331.                     {
  332.                         if(PacketLine > 0)
  333.                         {
  334.                             NeedChange = TRUE;
  335.                             PacketLine--;
  336.                         }
  337.                     }
  338.                 }
  339.             }
  340.  
  341.                 /* The user pressed the cursor-down key to
  342.                  * scroll through the command history.
  343.                  */
  344.  
  345.             if(Code == CURSORDOWN)
  346.             {
  347.                 if(IsListEmpty(&PacketHistoryList))
  348.                     PacketLine = -1;
  349.                 else
  350.                 {
  351.                         /* Shift key: jump to last command
  352.                          * history entry.
  353.                          */
  354.  
  355.                     if(Qualifier & SHIFT_KEY)
  356.                     {
  357.                         NeedChange = TRUE;
  358.                         PacketLine = PacketCount - 1;
  359.                     }
  360.                     else
  361.                     {
  362.                         if(PacketLine != -1 && PacketLine < PacketCount - 1)
  363.                         {
  364.                             NeedChange = TRUE;
  365.                             PacketLine++;
  366.                         }
  367.                         else
  368.                         {
  369.                             NeedChange = TRUE;
  370.                             PacketLine = -1;
  371.                         }
  372.                     }
  373.                 }
  374.             }
  375.  
  376.             break;
  377.     }
  378.  
  379.         /* Check if we have to update the string gadget contents. */
  380.  
  381.     if(NeedChange)
  382.     {
  383.         STRPTR String;
  384.  
  385.         String = "";
  386.  
  387.         if(PacketLine != -1)
  388.         {
  389.             if(Node = GetListNode(PacketLine,&PacketHistoryList))
  390.             {
  391.                 if(HasList)
  392.                 {
  393.                     String = NULL;
  394.  
  395.                     GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  396.                         GTLV_Selected,PacketLine,
  397.                     TAG_DONE);
  398.                 }
  399.                 else
  400.                     String = Node->ln_Name;
  401.             }
  402.         }
  403.  
  404.         if(String)
  405.         {
  406.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  407.                 GTST_String,String,
  408.             TAG_DONE);
  409.         }
  410.     }
  411.  
  412.     if(Activate)
  413.         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  414. }
  415.  
  416.     /* HandlePacket():
  417.      *
  418.      *    Process the input coming through the packet window.
  419.      */
  420.  
  421. STATIC BOOL
  422. HandlePacket(VOID)
  423. {
  424.     ULONG Signals;
  425.  
  426.     while(TRUE)
  427.     {
  428.         Signals = Wait(PORTMASK(PacketWindow->UserPort) | SIG_KILL | SIGBREAKF_CTRL_F);
  429.  
  430.         if(Signals & SIG_KILL)
  431.             return(TRUE);
  432.  
  433.         if(Signals & SIGBREAKF_CTRL_F)
  434.         {
  435.             WindowToFront(PacketWindow);
  436.             ActivateWindow(PacketWindow);
  437.         }
  438.  
  439.         if(Signals & PORTMASK(PacketWindow->UserPort))
  440.         {
  441.             struct IntuiMessage        *Message;
  442.             ULONG                     MsgClass,MsgCode;
  443.             struct Gadget            *MsgGadget;
  444.             struct FileRequester    *FileRequest;
  445.             UBYTE                     DummyBuffer[MAX_FILENAME_LENGTH];
  446.             BOOL                     SwapWindow;
  447.  
  448.             SwapWindow = FALSE;
  449.  
  450.             while(Message = (struct IntuiMessage *)GT_GetIMsg(PacketWindow->UserPort))
  451.             {
  452.                 MsgClass    = Message->Class;
  453.                 MsgCode        = Message->Code;
  454.                 MsgGadget    = (struct Gadget *)Message->IAddress;
  455.  
  456.                 GT_ReplyIMsg(Message);
  457.  
  458.                     /* Re-enable the string gadget if necessary. */
  459.  
  460.                 if(MsgClass == IDCMP_RAWKEY)
  461.                 {
  462.                     if(MsgCode == (IECODE_UP_PREFIX|RAMIGA_CODE) && CommandWindow == PacketWindow)
  463.                         ActivateGadget(CommandGadget,PacketWindow,NULL);
  464.  
  465.                     if(MsgCode == HELP_CODE)
  466.                         GuideDisplay(CONTEXT_PACKETWINDOW);
  467.                 }
  468.  
  469.                     /* Menu help is required. */
  470.  
  471.                 if(MsgClass == IDCMP_MENUHELP)
  472.                     GuideDisplay(CONTEXT_PACKET_MENU);
  473.  
  474.                     /* Imagery may need refreshing */
  475.  
  476.                 if(MsgClass == IDCMP_REFRESHWINDOW)
  477.                 {
  478.                     GT_BeginRefresh(PacketWindow);
  479.                     GT_EndRefresh(PacketWindow,TRUE);
  480.                 }
  481.  
  482.                     /* Handle the menu. */
  483.  
  484.                 if(MsgClass == IDCMP_MENUPICK)
  485.                 {
  486.                     struct MenuItem *MenuItem;
  487.  
  488.                     while(MsgCode != MENUNULL)
  489.                     {
  490.                         MenuItem = ItemAddress(PacketMenu,MsgCode);
  491.  
  492.                         switch((ULONG)GTMENUITEM_USERDATA(MenuItem))
  493.                         {
  494.                             case MEN_TOGGLE_ECHO:
  495.  
  496.                                 if(MenuItem->Flags & CHECKED)
  497.                                     Echo = TRUE;
  498.                                 else
  499.                                     Echo = FALSE;
  500.  
  501.                                 break;
  502.  
  503.                             case MEN_QUITPANEL:
  504.  
  505.                                 MsgClass = IDCMP_CLOSEWINDOW;
  506.                                 break;
  507.  
  508.                             case MEN_LOADHISTORY:
  509.  
  510.                                 LT_LockWindow(PacketWindow);
  511.  
  512.                                 DummyBuffer[0] = 0;
  513.  
  514.                                 if(FileRequest = OpenSingleFile(PacketWindow,LocaleString(MSG_PACKET_LOAD_HISTORY_TXT),NULL,NULL,DummyBuffer,sizeof(DummyBuffer)))
  515.                                 {
  516.                                     FreeAslRequest(FileRequest);
  517.  
  518.                                     if(GetFileSize(DummyBuffer))
  519.                                     {
  520.                                         BPTR SomeFile;
  521.  
  522.                                         if(SomeFile = Open(DummyBuffer,MODE_OLDFILE))
  523.                                         {
  524.                                             if(PacketLine)
  525.                                             {
  526.                                                 switch(ShowRequest(PacketWindow,LocaleString(MSG_PACKET_PACKET_WINDOW_STILL_HOLDS_LINES_TXT),LocaleString(MSG_PACKET_DISCARD_APPEND_CANCEL_TXT),PacketLine))
  527.                                                 {
  528.                                                     case 1:
  529.  
  530.                                                         ClearPacketHistory();
  531.                                                         break;
  532.  
  533.                                                     case 0:
  534.  
  535.                                                         Close(SomeFile);
  536.                                                         SomeFile = NULL;
  537.                                                         break;
  538.                                                 }
  539.                                             }
  540.  
  541.                                             if(SomeFile)
  542.                                             {
  543.                                                 LONG Len;
  544.  
  545.                                                 LineRead(NULL,NULL,NULL);
  546.  
  547.                                                 while(Len = LineRead(SomeFile,DummyBuffer,sizeof(DummyBuffer) - 1))
  548.                                                 {
  549.                                                     DummyBuffer[Len - 1] = 0;
  550.  
  551.                                                     AddPacketHistory(DummyBuffer);
  552.                                                 }
  553.  
  554.                                                 Close(SomeFile);
  555.                                             }
  556.                                         }
  557.                                         else
  558.                                             ShowError(PacketWindow,ERR_LOAD_ERROR,IoErr(),DummyBuffer);
  559.                                     }
  560.                                 }
  561.  
  562.                                 LT_UnlockWindow(PacketWindow);
  563.                                 break;
  564.  
  565.                             case MEN_SAVEHISTORY:
  566.  
  567.                                 LT_LockWindow(PacketWindow);
  568.  
  569.                                 if(!PacketLine)
  570.                                     ShowRequest(PacketWindow,LocaleString(MSG_PACKET_NOTHING_IN_THE_BUFFER_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT));
  571.                                 else
  572.                                 {
  573.                                     DummyBuffer[0] = 0;
  574.  
  575.                                     if(FileRequest = SaveFile(PacketWindow,LocaleString(MSG_PACKET_SAVE_HISTORY_TXT),NULL,NULL,DummyBuffer,sizeof(DummyBuffer)))
  576.                                     {
  577.                                         BPTR SomeFile = NULL;
  578.                                         LONG Error = 0;
  579.  
  580.                                         FreeAslRequest(FileRequest);
  581.  
  582.                                             /* If the file we are about
  583.                                              * to create already exists,
  584.                                              * ask the user whether we are
  585.                                              * to create, append or skip
  586.                                              * the file.
  587.                                              */
  588.  
  589.                                         if(GetFileSize(DummyBuffer))
  590.                                         {
  591.                                             switch(ShowRequest(PacketWindow,LocaleString(MSG_GLOBAL_FILE_ALREADY_EXISTS_TXT),LocaleString(MSG_GLOBAL_CREATE_APPEND_CANCEL_TXT),DummyBuffer))
  592.                                             {
  593.                                                 case 1:
  594.  
  595.                                                     SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  596.                                                     break;
  597.  
  598.                                                 case 2:
  599.  
  600.                                                     SomeFile = OpenToAppend(DummyBuffer,NULL);
  601.                                                     break;
  602.                                             }
  603.                                         }
  604.                                         else
  605.                                             SomeFile = Open(DummyBuffer,MODE_NEWFILE);
  606.  
  607.                                         if(!SomeFile)
  608.                                             Error = IoErr();
  609.                                         else
  610.                                         {
  611.                                             struct Node *SomeNode;
  612.  
  613.                                             ObtainSemaphore(&PacketSemaphore);
  614.  
  615.                                             for(SomeNode = PacketHistoryList.lh_Head ; SomeNode->ln_Succ ; SomeNode = SomeNode->ln_Succ)
  616.                                             {
  617.                                                 SetIoErr(0);
  618.  
  619.                                                 if(FPrintf(SomeFile,"%s\n",SomeNode->ln_Name) < 1)
  620.                                                 {
  621.                                                     Error = IoErr();
  622.  
  623.                                                     break;
  624.                                                 }
  625.                                             }
  626.  
  627.                                             Close(SomeFile);
  628.  
  629.                                             if(GetFileSize(DummyBuffer))
  630.                                             {
  631.                                                 AddProtection(DummyBuffer,FIBF_EXECUTE);
  632.  
  633.                                                 if(Config->MiscConfig->CreateIcons)
  634.                                                     AddIcon(DummyBuffer,FILETYPE_TEXT,TRUE);
  635.                                             }
  636.                                             else
  637.                                                 DeleteFile(DummyBuffer);
  638.  
  639.                                             ReleaseSemaphore(&PacketSemaphore);
  640.                                         }
  641.  
  642.                                         if(Error)
  643.                                             ShowError(PacketWindow,ERR_SAVE_ERROR,Error,DummyBuffer);
  644.                                     }
  645.                                 }
  646.  
  647.                                 LT_UnlockWindow(PacketWindow);
  648.                                 break;
  649.  
  650.                             case MEN_CLEARHISTORY:
  651.  
  652.                                 LT_LockWindow(PacketWindow);
  653.  
  654.                                 ClearPacketHistory();
  655.  
  656.                                 LT_UnlockWindow(PacketWindow);
  657.                                 break;
  658.  
  659.                             case MEN_OTHERWINDOW:
  660.  
  661.                                 SwapWindow = TRUE;
  662.                                 break;
  663.                         }
  664.  
  665.                         MsgCode = MenuItem->NextSelect;
  666.                     }
  667.  
  668.                     ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  669.                 }
  670.  
  671.                     /* Shut down. */
  672.  
  673.                 if(MsgClass == IDCMP_CLOSEWINDOW)
  674.                 {
  675.                     Forbid();
  676.  
  677.                     if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  678.                         return(FALSE);
  679.                     else
  680.                         return(TRUE);
  681.                 }
  682.  
  683.                     /* Activate the string gadget as well. */
  684.  
  685.                 if(MsgClass == IDCMP_ACTIVEWINDOW)
  686.                     ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  687.  
  688.                 if(MsgClass == IDCMP_NEWSIZE)
  689.                 {
  690.                     PacketWindow->Flags |= WFLG_RMBTRAP;
  691.  
  692.                     strcpy(PacketTempBuffer,PacketContents);
  693.  
  694.                     RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  695.  
  696.                     FreeGadgets(PacketGadgetList);
  697.                     PacketGadgetList = NULL;
  698.  
  699.                     EraseWindow(PacketWindow,NULL);
  700.                     RefreshWindowFrame(PacketWindow);
  701.  
  702.                     ObtainSemaphore(&PacketSemaphore);
  703.  
  704.                     if(CreateAllGadgets(PacketWindow->Width,PacketWindow->Height,NULL,PacketGadgetArray,&PacketGadgetList,VisualInfo))
  705.                     {
  706.                         PacketContents = ((struct StringInfo *)PacketGadgetArray[GAD_STRING]->SpecialInfo)->Buffer;
  707.  
  708.                         AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  709.                         RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  710.                         GT_RefreshWindow(PacketWindow,NULL);
  711.  
  712.                         ReleaseSemaphore(&PacketSemaphore);
  713.  
  714.                         PacketWindow->Flags &= ~WFLG_RMBTRAP;
  715.  
  716.                         GT_SetGadgetAttrs(PacketGadgetArray[GAD_STRING],PacketWindow,NULL,
  717.                             GTST_String,    PacketTempBuffer,
  718.                         TAG_DONE);
  719.  
  720.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  721.                     }
  722.                     else
  723.                     {
  724.                         DisplayBeep(PacketWindow->WScreen);
  725.  
  726.                         ReleaseSemaphore(&PacketSemaphore);
  727.  
  728.                         if(!(SetSignal(0,SIG_KILL) & SIG_KILL))
  729.                             return(FALSE);
  730.                         else
  731.                             return(TRUE);
  732.                     }
  733.                 }
  734.  
  735.                 if(MsgClass == IDCMP_MOUSEBUTTONS)
  736.                     ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  737.  
  738.                     /* User has entered a string. */
  739.  
  740.                 if(MsgClass == IDCMP_GADGETUP)
  741.                 {
  742.                     switch(MsgGadget->GadgetID)
  743.                     {
  744.                         case GAD_STRING:
  745.  
  746.                             HandlePacketGadgetEvent(MsgCode);
  747.                             break;
  748.  
  749.                         case GAD_LIST:
  750.  
  751.                             ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  752.                             break;
  753.                     }
  754.                 }
  755.  
  756.                 if(SwapWindow)
  757.                 {
  758.                     BumpWindow(Window);
  759.  
  760.                     SwapWindow = FALSE;
  761.                 }
  762.             }
  763.         }
  764.     }
  765. }
  766.  
  767. STATIC VOID SAVE_DS
  768. PacketProcessEntry(VOID)
  769. {
  770.     BOOL RingBack = TRUE;
  771.  
  772.     if(PacketTempBuffer = (STRPTR)AllocVecPooled(MAX_PACKET_LINE_LENGTH,MEMF_ANY))
  773.     {
  774.         if((PacketSignal = AllocSignal(-1)) != -1)
  775.         {
  776.             STATIC ULONG MenuTags[] =
  777.             {
  778.                 LAMN_TitleID,            MSG_PACKET_PROJECT_MEN,
  779.                     LAMN_ItemID,        MSG_PACKET_LOAD_HISTORY_MEN,
  780.                         LAMN_UserData,    MEN_LOADHISTORY,
  781.                     LAMN_ItemID,        MSG_PACKET_SAVE_HISTORY_MEN,
  782.                         LAMN_UserData,    MEN_SAVEHISTORY,
  783.                     LAMN_ItemID,        MSG_PACKET_CLEAR_HISTORY_MEN,
  784.                         LAMN_UserData,    MEN_CLEARHISTORY,
  785.  
  786.                     LAMN_ItemText,        (ULONG)NM_BARLABEL,
  787.  
  788.                     LAMN_ItemID,        MSG_PACKET_OTHER_WINDOW_MEN,
  789.                         LAMN_UserData,    MEN_OTHERWINDOW,
  790.  
  791.                     LAMN_ItemText,        (ULONG)NM_BARLABEL,
  792.  
  793.                     LAMN_ItemID,        MSG_PACKET_TOGGLE_ECHO_MEN,
  794.                         LAMN_UserData,    MEN_TOGGLE_ECHO,
  795.                         LAMN_Toggle,    TRUE,
  796.  
  797.                     LAMN_ItemText,        (ULONG)NM_BARLABEL,
  798.  
  799.                     LAMN_ItemID,        MSG_PACKET_QUIT_MEN,
  800.                         LAMN_UserData,    MEN_QUITPANEL,
  801.  
  802.                 TAG_DONE
  803.             };
  804.  
  805.             if(PacketMenu = LT_NewMenuTags(
  806.                 LAHN_LocaleHook,        &LocaleHook,
  807.                 LAMN_Screen,            Window->WScreen,
  808.                 LAMN_TextAttr,            Window->WScreen->Font,
  809.                 LAMN_AmigaGlyph,        AmigaGlyph,
  810.                 LAMN_CheckmarkGlyph,    CheckGlyph,
  811.             TAG_MORE,MenuTags))
  812.             {
  813.                 LONG PacketLeft,PacketTop,PacketWidth,PacketHeight,MinHeight;
  814.  
  815.                 PacketLeft        = Window->LeftEdge;
  816.                 PacketTop        = Window->TopEdge + Window->Height;
  817.                 PacketWidth        = Window->Width;
  818.                 PacketHeight    = Window->WScreen->WBorTop + Window->WScreen->Font->ta_YSize + 1 + 1 + 3 + TextAttr.tta_YSize + 3 + 1 + Window->WScreen->WBorBottom;
  819.  
  820.                 GetWindowInfo(WINDOW_PACKET,&PacketLeft,&PacketTop,&PacketWidth,&PacketHeight,PacketWidth,PacketHeight);
  821.  
  822.                 if(CreateAllGadgets(PacketWidth,PacketHeight,&MinHeight,PacketGadgetArray,&PacketGadgetList,VisualInfo))
  823.                 {
  824.                     if(PacketWindow = OpenWindowTags(NULL,
  825.                         WA_Width,            PacketWidth,
  826.                         WA_Height,            PacketHeight,
  827.  
  828.                         WA_Left,            PacketLeft,
  829.                         WA_Top,                PacketTop,
  830.  
  831.                         WA_Activate,        TRUE,
  832.                         WA_DragBar,            TRUE,
  833.                         WA_DepthGadget,        TRUE,
  834.                         WA_CloseGadget,        TRUE,
  835.                         WA_RMBTrap,            TRUE,
  836.                         WA_SizeGadget,        TRUE,
  837.                         WA_MinWidth,        Window->BorderLeft+80+Window->BorderRight,
  838.                         WA_MinHeight,        MinHeight,
  839.                         WA_MaxWidth,        Window->WScreen->Width,
  840.                         WA_MaxHeight,        Window->WScreen->Height,
  841.                         OpenWindowTag,        Window->WScreen,
  842.                         WA_NewLookMenus,    TRUE,
  843.                         WA_SimpleRefresh,    TRUE,
  844.                         BackfillTag,        &BackfillHook,
  845.  
  846.                         WA_IDCMP,            STRINGIDCMP | LISTVIEWIDCMP | IDCMP_NEWSIZE | IDCMP_SIZEVERIFY | IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | IDCMP_ACTIVEWINDOW | IDCMP_RAWKEY | IDCMP_MOUSEBUTTONS | IDCMP_MENUHELP | IDCMP_REFRESHWINDOW,
  847.                         WA_MenuHelp,        TRUE,
  848.  
  849.                         WA_Title,            LocaleString(MSG_GLOBAL_PACKET_WINDOW_TXT),
  850.  
  851.                         AmigaGlyph ? WA_AmigaKey  : TAG_IGNORE, AmigaGlyph,
  852.                         CheckGlyph ? WA_Checkmark : TAG_IGNORE, CheckGlyph,
  853.                     TAG_DONE))
  854.                     {
  855.                         APTR OldPtr;
  856.  
  857.                         PacketContents = ((struct StringInfo *)PacketGadgetArray[GAD_STRING]->SpecialInfo)->Buffer;
  858.  
  859.                         AddGList(PacketWindow,PacketGadgetList,(UWORD)-1,(UWORD)-1,NULL);
  860.                         RefreshGList(PacketGadgetList,PacketWindow,NULL,(UWORD)-1);
  861.                         GT_RefreshWindow(PacketWindow,NULL);
  862.  
  863.                         SetMenuStrip(PacketWindow,PacketMenu);
  864.  
  865.                         PacketWindow->Flags &= ~WFLG_RMBTRAP;
  866.  
  867.                         ActivateGadget(PacketGadgetArray[GAD_STRING],PacketWindow,NULL);
  868.  
  869.                         PacketProcess = (struct Process *)FindTask(NULL);
  870.  
  871.                         ChangeWindowPtr(&OldPtr,(APTR)PacketWindow);
  872.  
  873.                         Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  874.  
  875.                         RingBack = HandlePacket();
  876.  
  877.                         RestoreWindowPtr(OldPtr);
  878.  
  879.                         PacketWindow->Flags |= WFLG_RMBTRAP;
  880.  
  881.                         ClearMenuStrip(PacketWindow);
  882.  
  883.                         RemoveGList(PacketWindow,PacketGadgetList,(UWORD)-1);
  884.  
  885.                         PutWindowInfo(WINDOW_PACKET,PacketWindow->LeftEdge,PacketWindow->TopEdge,PacketWindow->Width,PacketWindow->Height);
  886.  
  887.                         LT_DeleteWindowLock(PacketWindow);
  888.  
  889.                         CloseWindow(PacketWindow);
  890.                         PacketWindow = NULL;
  891.                     }
  892.  
  893.                     FreeGadgets(PacketGadgetList);
  894.                     PacketGadgetList = NULL;
  895.                 }
  896.  
  897.                 LT_DisposeMenu(PacketMenu);
  898.                 PacketMenu = NULL;
  899.             }
  900.  
  901.             FreeSignal(PacketSignal);
  902.             PacketSignal = -1;
  903.         }
  904.  
  905.         FreeVecPooled(PacketTempBuffer);
  906.     }
  907.  
  908.     Forbid();
  909.  
  910.     PacketProcess = NULL;
  911.  
  912.     if(RingBack)
  913.         Signal((struct Task *)ThisProcess,SIG_HANDSHAKE);
  914.     else
  915.         CheckItem(MEN_PACKET_WINDOW,FALSE);
  916. }
  917.  
  918.     /* ClearPacketHistory():
  919.      *
  920.      *    Release the command history.
  921.      */
  922.  
  923. VOID
  924. ClearPacketHistory()
  925. {
  926.     if(PacketProcess)
  927.     {
  928.         ObtainSemaphore(&PacketSemaphore);
  929.  
  930.         if(HasList)
  931.         {
  932.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  933.                 GTLV_Labels,~0,
  934.             TAG_DONE);
  935.         }
  936.  
  937.         FreeList(&PacketHistoryList);
  938.  
  939.         PacketCount    = 0;
  940.         PacketLine    = -1;
  941.  
  942.         if(HasList)
  943.         {
  944.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  945.                 GTLV_Labels,&PacketHistoryList,
  946.             TAG_DONE);
  947.         }
  948.  
  949.         ReleaseSemaphore(&PacketSemaphore);
  950.     }
  951. }
  952.  
  953.     /* AddPacketHistory(STRPTR Buffer):
  954.      *
  955.      *    Add a line to the packet window command history. This
  956.      *    works very much the same as the AddLine()-routine.
  957.      */
  958.  
  959. VOID
  960. AddPacketHistory(STRPTR Buffer)
  961. {
  962.     if(PacketProcess)
  963.     {
  964.         struct Node *Node;
  965.  
  966.         ObtainSemaphore(&PacketSemaphore);
  967.  
  968.         if(HasList)
  969.         {
  970.             GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  971.                 GTLV_Labels, ~0,
  972.             TAG_DONE);
  973.         }
  974.  
  975.         if(Node = CreateNode(Buffer))
  976.         {
  977.             AddTail(&PacketHistoryList,Node);
  978.  
  979.             if(HasList)
  980.             {
  981.                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  982.                     GTLV_Top,        PacketCount,
  983.                     GTLV_Labels,    &PacketHistoryList,
  984.                 TAG_DONE);
  985.             }
  986.  
  987.             PacketCount++;
  988.         }
  989.         else
  990.         {
  991.             if(HasList)
  992.             {
  993.                 GT_SetGadgetAttrs(PacketGadgetArray[GAD_LIST],PacketWindow,NULL,
  994.                     GTLV_Labels, &PacketHistoryList,
  995.                 TAG_DONE);
  996.             }
  997.         }
  998.  
  999.         ReleaseSemaphore(&PacketSemaphore);
  1000.     }
  1001. }
  1002.  
  1003.     /* DeletePacketWindow():
  1004.      *
  1005.      *    Delete the packet window and release the command
  1006.      *    history.
  1007.      */
  1008.  
  1009. VOID
  1010. DeletePacketWindow(BOOL WindowOnly)
  1011. {
  1012.     CheckItem(MEN_PACKET_WINDOW,FALSE);
  1013.  
  1014.     if(PacketProcess)
  1015.     {
  1016.         ShakeHands((struct Task *)PacketProcess,SIG_KILL);
  1017.  
  1018.         if(!WindowOnly)
  1019.         {
  1020.             HasList = FALSE;
  1021.  
  1022.             FreeList(&PacketHistoryList);
  1023.  
  1024.             PacketCount    = -1;
  1025.             PacketLine    = 0;
  1026.         }
  1027.     }
  1028. }
  1029.  
  1030.     /* CreatePacketWindow():
  1031.      *
  1032.      *    Open the packet window and allocate the command history
  1033.      *    buffer.
  1034.      */
  1035.  
  1036. BOOL
  1037. CreatePacketWindow()
  1038. {
  1039.     BOOL Result;
  1040.  
  1041.     if(Echo == -1)
  1042.         Echo = Config->SerialConfig->Duplex;
  1043.  
  1044.     if(!PacketProcess)
  1045.     {
  1046.         InitSemaphore(&PacketSemaphore);
  1047.  
  1048.         StartProcessWaitForHandshake("term Packet Process",(TASKENTRY)PacketProcessEntry,TAG_DONE);
  1049.     }
  1050.  
  1051.     Forbid();
  1052.  
  1053.     if(PacketProcess)
  1054.     {
  1055.         Signal((struct Task *)PacketProcess,SIGBREAKF_CTRL_F);
  1056.  
  1057.         Result = TRUE;
  1058.     }
  1059.     else
  1060.         Result = FALSE;
  1061.  
  1062.     Permit();
  1063.  
  1064.     CheckItem(MEN_PACKET_WINDOW,Result);
  1065.     return(Result);
  1066. }
  1067.